﻿using System.ComponentModel;
using System.Linq;
using System.Windows;
using Fayshine.VA.Helpers;
using Fayshine.VA.RIAService.Web;
using Fayshine.VA.Controls;
using Fayshine.VA.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System;
using System.Threading;
using System.Text;
using System.Diagnostics;

namespace Fayshine.VA.ViewModels
{
    public class WeekReportViewModel : INotifyPropertyChanged
    {
        #region Private Fields

        private FayshineDomainContext m_Context = null;

        private string m_CurveTitle = string.Empty;
        public event ResetHistoryChartEventHandler ResetHisotryChartEvent;
        public event AppendHistoryPassengerFlowEventHandler AppendHistoryPassengerFlow;
        public event AppendMultiHistoryPassengerEventHandler AppendMultiHistoryPassenger;

        private List<AreaExtend> m_checkedAreas;

        private List<MonitorAreaGateExt> m_checkedGates;

        #endregion

        #region Properties

        public ObservableCollection<AreaExtend> AreaExtends
        {
            get;
            set;
        }

        public ObservableCollection<MonitorAreaGateExt> MonitorAreaGateExts
        {
            get;
            set;
        }

        public ObservableCollection<AreaExtend> AreaExtends2
        {
            get;
            set;
        }

        public ObservableCollection<MonitorAreaGateExt> MonitorAreaGateExts2
        {
            get;
            set;
        }

        public IEnumerable<passengerflowbymin> TempPassengerFlowByMin
        {
            get;
            set;
        }

        public IEnumerable<passengerflowbydate> TempPassengerFlowByDate
        {
            set;
            get;
        }

        public List<ComparePassengerFlow> ComparePassengerFlows
        {
            get;
            set;
        }

        public List<WeekPassengerFlow> WeekPassengerFlows
        {
            get;
            set;
        }

        public string CurveTitle
        {
            get
            {
                return m_CurveTitle;
            }
            set
            {
                m_CurveTitle = value;
                NofityPropertyChanged("CurveTitle");
            }
        }

        public List<AreaExtend> CheckedAreas
        {
            get { return m_checkedAreas; }
        }

        public List<MonitorAreaGateExt> CheckedGates
        {
            get { return m_checkedGates; }
        }

        #endregion

        public WeekReportViewModel()
        {
            this.MonitorAreaGateExts = new ObservableCollection<MonitorAreaGateExt>();
            this.AreaExtends = new ObservableCollection<AreaExtend>();
            this.AreaExtends2 = new ObservableCollection<AreaExtend>();
            this.MonitorAreaGateExts2 = new ObservableCollection<MonitorAreaGateExt>();
            this.WeekPassengerFlows = new List<WeekPassengerFlow>();
            m_Context = new FayshineDomainContext();
        }

        #region Public methods

        public void GetAllAreas()
        {
            var getAreasQuery = m_Context.GetAreasQuery();
            var loadShopsOperation = m_Context.Load(getAreasQuery, (s) =>
            {
                if (!s.HasError)
                {
                    AreaExtend tempAreaExt = null;
                    AreaExtend tempAreaExt2 = null;
                    s.Entities.ToList().ForEach(e =>
                    {
                        tempAreaExt = new AreaExtend();
                        tempAreaExt.ID = e.ID;
                        tempAreaExt.Name = e.Name;
                        tempAreaExt.Tag = e;
                        tempAreaExt.IsSelected = false;
                        this.AreaExtends.Add(tempAreaExt);

                        tempAreaExt2 = new AreaExtend();
                        tempAreaExt2.ID = e.ID;
                        tempAreaExt2.Name = e.Name;
                        tempAreaExt2.Tag = e;
                        tempAreaExt2.IsSelected = false;
                        this.AreaExtends2.Add(tempAreaExt2);
                    });
                }
                else
                {
                    MessageBox.Show(s.Error.Message + s.Error.StackTrace);
                }
                BusyIndicator indicator = Application.Current.RootVisual as BusyIndicator;
                indicator.IsBusy = false;
            }, true);
        }

        public void SelectAreasChanged(List<area> areas)
        {
            if (areas.Count > 0)
            {
                this.MonitorAreaGateExts.Clear();
                MonitorAreaGateExt tempMonitorExt;
                if (areas.Count == 1)
                {
                    MonitorAreaGateExt topMonitorExt = new MonitorAreaGateExt();
                    topMonitorExt.ID = areas[0].ID;
                    topMonitorExt.Name = "全部";
                    topMonitorExt.ParentID = areas[0].ParentID;
                    topMonitorExt.TypeID = 1;
                    topMonitorExt.IsSelected = true;
                    this.MonitorAreaGateExts.Add(topMonitorExt);

                    areas[0].gates.OrderBy(o => o.ID).each(e =>
                    {
                        tempMonitorExt = new MonitorAreaGateExt();
                        tempMonitorExt.ID = e.ID;
                        tempMonitorExt.ParentID = areas[0].ID;
                        tempMonitorExt.Name = e.Name;
                        tempMonitorExt.TypeID = 0;
                        tempMonitorExt.ParentMonitor = topMonitorExt;
                        tempMonitorExt.IsSelected = true;
                        topMonitorExt.Childs.Add(tempMonitorExt);
                        this.MonitorAreaGateExts.Add(tempMonitorExt);
                    });

                }
                else
                {
                    areas.each(a =>
                    {
                        tempMonitorExt = new MonitorAreaGateExt();
                        tempMonitorExt.ID = a.ID;
                        tempMonitorExt.Name = a.Name;
                        tempMonitorExt.ParentID = a.ParentID;
                        tempMonitorExt.TypeID = 1;
                        this.MonitorAreaGateExts.Add(tempMonitorExt);
                    });

                    tempMonitorExt = new MonitorAreaGateExt();
                    tempMonitorExt.ID = -1;
                    tempMonitorExt.Name = "所选店铺总和";
                    tempMonitorExt.ParentID = null;
                    tempMonitorExt.TypeID = 2;
                    this.MonitorAreaGateExts.Add(tempMonitorExt);
                }

            }
        }

        public void SelectAreasChanged2(List<area> areas)
        {
            if (areas.Count > 0)
            {
                this.MonitorAreaGateExts2.Clear();
                MonitorAreaGateExt tempMonitorExt;
                if (areas.Count == 1)
                {
                    MonitorAreaGateExt topMonitorExt = new MonitorAreaGateExt();
                    topMonitorExt.ID = areas[0].ID;
                    topMonitorExt.Name = "全部";
                    topMonitorExt.ParentID = areas[0].ParentID;
                    topMonitorExt.TypeID = 1;
                    topMonitorExt.IsSelected = true;
                    this.MonitorAreaGateExts2.Add(topMonitorExt);

                    areas[0].gates.OrderBy(o => o.ID).each(e =>
                    {
                        tempMonitorExt = new MonitorAreaGateExt();
                        tempMonitorExt.ID = e.ID;
                        tempMonitorExt.ParentID = areas[0].ID;
                        tempMonitorExt.Name = e.Name;
                        tempMonitorExt.TypeID = 0;
                        tempMonitorExt.ParentMonitor = topMonitorExt;
                        tempMonitorExt.IsSelected = true;
                        topMonitorExt.Childs.Add(tempMonitorExt);
                        this.MonitorAreaGateExts2.Add(tempMonitorExt);
                    });

                }
                else
                {
                    areas.each(a =>
                    {
                        tempMonitorExt = new MonitorAreaGateExt();
                        tempMonitorExt.ID = a.ID;
                        tempMonitorExt.Name = a.Name;
                        tempMonitorExt.ParentID = a.ParentID;
                        tempMonitorExt.TypeID = 1;
                        this.MonitorAreaGateExts2.Add(tempMonitorExt);
                    });

                    tempMonitorExt = new MonitorAreaGateExt();
                    tempMonitorExt.ID = -1;
                    tempMonitorExt.Name = "所选店铺总和";
                    tempMonitorExt.ParentID = null;
                    tempMonitorExt.TypeID = 2;
                    this.MonitorAreaGateExts2.Add(tempMonitorExt);
                }

            }
        }

        public List<HistoryPassengerFlow> GetHistoryPassengerByWeek(bool isAvg, DateTime startTime, DateTime endTime, List<DayOfWeek> enbaleWeeks)
        {
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;
            var firstDurationPassengers = GetAnyDurationHistoryPassengerFlow(isSingleArea, this.TempPassengerFlowByMin, startTime, endTime, enbaleWeeks);

            return CompoundHistoryPassengerFlow(isAvg, firstDurationPassengers);
        }

        public List<HistoryPassengerFlow> GetWeekHistoryPassengerFlowByGate(bool isSingleArea, int id,DateTime dateTime)
        {
            List<HistoryPassengerFlow> historyPassengerFlows = new List<HistoryPassengerFlow>();
            WeekPassengerFlow gateWeekPassengerFlow = null;
            string name = string.Empty;
            if (isSingleArea)
            {
                gateWeekPassengerFlow = this.WeekPassengerFlows.Where(entity => id == entity.GateID).FirstOrDefault();
                name = GetGateName(id);
            }
            else
            {
                var selectAreaExt = this.AreaExtends.Where(a => a.ID == id).FirstOrDefault();
                if (selectAreaExt != null)
                {
                    name = selectAreaExt.Name;
                    var ids = GetGateIDsByArea(selectAreaExt.ID);
                     gateWeekPassengerFlow = this.WeekPassengerFlows.Where(entity => id == entity.GateID).FirstOrDefault();
                    //historyPassengerFlows = ConvertYearHistoryPassengerFlow(tempPassengerFlows, year);
                }
            }

            if (gateWeekPassengerFlow != null)
            {
                DateTime startTime = dateTime;
                DateTime endTime = dateTime;
                GetWeekStartAndEndTime(dateTime, out startTime, out endTime);

                HistoryPassengerFlow tempHistoryPassengerFlow = null;
                while (startTime < endTime)
                {

                    tempHistoryPassengerFlow = new HistoryPassengerFlow();
                    tempHistoryPassengerFlow.DisplayTitle = startTime.ToShortDateString() +"\r\n"+ FayshineManager.Instance.GetWeekDayString(startTime.DayOfWeek);
                    tempHistoryPassengerFlow.GateName = name;
                    switch (startTime.DayOfWeek)
                    {
                        case DayOfWeek.Monday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.MonDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.MonDayOutCount;
                            break;
                        case DayOfWeek.Tuesday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.TueDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.TueDayOutCount;
                            break;
                        case DayOfWeek.Wednesday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.WedDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.WedDayOutCount;
                            break;
                        case DayOfWeek.Thursday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.ThuDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.ThuDayOutCount;
                            break;
                        case DayOfWeek.Friday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.FriDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.FriDayOutCount;
                            break;
                        case DayOfWeek.Saturday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.SatDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.SatDayOutCount;
                            break;
                        case DayOfWeek.Sunday:
                            tempHistoryPassengerFlow.InCount = gateWeekPassengerFlow.SunDayInCount;
                            tempHistoryPassengerFlow.OutCount = gateWeekPassengerFlow.SunDayOutCount;
                            break;
                    }

                    historyPassengerFlows.Add(tempHistoryPassengerFlow);
                    startTime = startTime.AddDays(1);
                }

            }

            return historyPassengerFlows;
        }

        #endregion

        #region 周报表分析

        public void RefreshWeekReport(bool isIn, DateTime dateTime)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;

            var getWeekDayPassengerQuery = m_Context.GetPassengerflowByWeekQuery(monitorAreaIDs, dateTime);

            var loadMonthPassgnerQuery = m_Context.Load(getWeekDayPassengerQuery, (s) =>
            {
                if (!s.HasError)
                {
                    DateTime startTime = dateTime;
                    DateTime endTime = dateTime;
                    GetWeekStartAndEndTime(dateTime, out startTime, out endTime);
                    var thisWeekDayPassneger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, startTime, endTime);
                    var thisWeekGatePassenger = GetGateWeekDayPassengerFlow(isSingleArea, s.Entities.ToList(), startTime, endTime);

                    DateTime lastStartTime = dateTime.AddDays(-7);
                    DateTime lastEndTime = dateTime.AddDays(-7);
                    GetWeekStartAndEndTime(dateTime.AddDays(-7), out lastStartTime, out lastEndTime);
                    var lastWeekDayPassenger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, lastStartTime, lastEndTime);

                    DateTime lastYearStartTime = dateTime.AddYears(-1);
                    DateTime lastYearEndTime = dateTime.AddYears(-1);
                    GetWeekStartAndEndTime(dateTime.AddYears(-1), out lastYearStartTime, out lastYearEndTime);
                    var lastYearWeekDayPassenger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, lastYearStartTime, lastYearEndTime);

                    m_Context.passengerflowbydates.Clear();

                    var getYearWeekPassengerQuery = m_Context.GetPassengerflowByYearWeekQuery(monitorAreaIDs, dateTime.Year);

                    var loadYearPassgnerQuery = m_Context.Load(getYearWeekPassengerQuery, (t) =>
                    {
                        if (!t.HasError)
                        {
                            var thisYearWeekPassneger = GetYearWeekPassengerFlow(isSingleArea, t.Entities, dateTime.Year);
                            var lastYearWeekPassenger = GetYearWeekPassengerFlow(isSingleArea, t.Entities, dateTime.Year - 1);
                            //var thisYearHistoryPassenger = GetMonthHistoryPassengerFlow(isSingleArea, t.Entities.ToList(), dateTime.Year, dateTime.Month);
                            if (AppendMultiHistoryPassenger != null)
                            {
                                AppendMultiHistoryPassenger(this.CurveTitle, isIn,
                                                            thisWeekDayPassneger,
                                                            lastWeekDayPassenger,
                                                            lastYearWeekDayPassenger,
                                                            thisYearWeekPassneger,
                                                            lastYearWeekPassenger,
                                                            thisWeekGatePassenger);
                            }
                        }
                    }, true);
                }
            }, true);

            //Set DateTime Query
            DateTime startDayTime = dateTime;
            DateTime endDayTime = dateTime;
            GetWeekStartAndEndTime(dateTime, out startDayTime, out endDayTime);
            var getDurationPassengerQuery = m_Context.GetPassengerflowbySpecifiedTimeQuery(monitorAreaIDs, 30, startDayTime, endDayTime);
            var loadDuaraionPassgnerQuery = m_Context.Load(getDurationPassengerQuery, (a) =>
            {
                if (!a.HasError)
                {
                    var firstDurationPassengers = GetAnyDurationHistoryPassengerFlow(isSingleArea, a.Entities, startDayTime, endDayTime, null);
                    this.TempPassengerFlowByMin = a.Entities;
                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(string.Empty, isIn,
                                                    CompoundHistoryPassengerFlow(false, firstDurationPassengers), null);
                    }

                }
            }, true);

        }

        public List<HistoryPassengerFlow> GetWeekDayPassengerFlow(bool isSingleArea, IEnumerable<passengerflowbydate> entities, DateTime startTime, DateTime endTime)
        {
            List<HistoryPassengerFlow> historyPassengerFlows = new List<HistoryPassengerFlow>();
            List<passengerflowbydate> tempPassengerFlows = new List<passengerflowbydate>();
            if (isSingleArea)
            {
                var topAreaGate = this.MonitorAreaGateExts.Where(m => m.TypeID == 1).FirstOrDefault();
                if (topAreaGate != null)
                {
                    List<int> ids = new List<int>();
                    if (topAreaGate.IsSelected)
                    {
                        ids = GetGateIDsByArea(topAreaGate.ID);
                    }
                    else
                    {
                        ids = this.MonitorAreaGateExts.Where(m => m.IsSelected && m.TypeID != 1).Select(mm => mm.ID).ToList();
                    }
                    tempPassengerFlows = entities.Where(entity => ids.Contains(entity.gateID)).ToList();
                }
            }
            else
            {
                tempPassengerFlows = entities.ToList();
            }

            historyPassengerFlows = ConvertWeekDayHistoryPassengerFlow(tempPassengerFlows, startTime, endTime);
            return historyPassengerFlows;
        }

        private List<HistoryPassengerFlow> ConvertWeekDayHistoryPassengerFlow(List<passengerflowbydate> passengerflows, DateTime startTime, DateTime endTime)
        {
            List<HistoryPassengerFlow> weekDaysPassengerFlow = new List<HistoryPassengerFlow>();
            int lastInCount = 0;
            int lastOutCount = 0;
            while (startTime < endTime)
            {
                HistoryPassengerFlow historyPassengerFlow = new HistoryPassengerFlow();

                historyPassengerFlow.HistoryTime = startTime;
                historyPassengerFlow.DisplayDate = string.Format("{0:d}", startTime);
                historyPassengerFlow.DisplayTitle = FayshineManager.Instance.GetWeekDayString(startTime.DayOfWeek);
                historyPassengerFlow.MonthOrDayOrWeek = FayshineManager.Instance.GetWeekDayNumber(startTime.DayOfWeek);
                IEnumerable<int?> inCounts = from t in passengerflows
                                             where t.dt.Value == historyPassengerFlow.MonthOrDayOrWeek && t.historytime.Value.Month == startTime.Month
                                                   && t.historytime.Value.Year == startTime.Year && t.historytime.Value.Day == startTime.Day && t.isIn == true
                                             select t.count;
                IEnumerable<int?> outCounts = from t in passengerflows
                                              where t.dt.Value == historyPassengerFlow.MonthOrDayOrWeek && t.historytime.Value.Month == startTime.Month
                                                    && t.historytime.Value.Year == startTime.Year && t.historytime.Value.Day == startTime.Day && t.isIn == false
                                              select t.count;

                historyPassengerFlow.InCount = inCounts.Sum().Value;
                historyPassengerFlow.OutCount = outCounts.Sum().Value;
                historyPassengerFlow.AccumulateInCount = lastInCount + historyPassengerFlow.InCount;
                historyPassengerFlow.AccumulateOutCount = lastInCount + historyPassengerFlow.OutCount;
                historyPassengerFlow.StrandedCount = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
                historyPassengerFlow.AllInOut = historyPassengerFlow.InCount + historyPassengerFlow.OutCount;
                historyPassengerFlow.Differ = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
                lastInCount = historyPassengerFlow.AccumulateInCount;
                lastOutCount = historyPassengerFlow.AccumulateOutCount;

                weekDaysPassengerFlow.Add(historyPassengerFlow);
                startTime = startTime.AddDays(1);

            }

            return weekDaysPassengerFlow;
        }

        private List<HistoryPassengerFlow> GetYearWeekPassengerFlow(bool isSingleArea, IEnumerable<passengerflowbydate> entities, int year)
        {
            List<HistoryPassengerFlow> historyPassengerFlows = new List<HistoryPassengerFlow>();
            List<passengerflowbydate> tempPassengerFlows = new List<passengerflowbydate>();
            if (isSingleArea)
            {
                var topAreaGate = this.MonitorAreaGateExts.Where(m => m.TypeID == 1).FirstOrDefault();
                if (topAreaGate != null)
                {
                    List<int> ids = new List<int>();
                    if (topAreaGate.IsSelected)
                    {
                        ids = GetGateIDsByArea(topAreaGate.ID);
                    }
                    else
                    {
                        ids = this.MonitorAreaGateExts.Where(m => m.IsSelected && m.TypeID != 1).Select(mm => mm.ID).ToList();
                    }
                    tempPassengerFlows = entities.Where(entity => ids.Contains(entity.gateID)).ToList();
                }
            }
            else
            {
                tempPassengerFlows = entities.ToList();
            }

            historyPassengerFlows = ConvertYearWeekHistoryPassengerFlow(tempPassengerFlows, year);
            return historyPassengerFlows;
        }

        private List<HistoryPassengerFlow> ConvertYearWeekHistoryPassengerFlow(List<passengerflowbydate> passengerflows, int year)
        {
            List<HistoryPassengerFlow> yearWeeksPassengerFlow = new List<HistoryPassengerFlow>();
            int firstWeek = 1;
            int endWeek = 53;// FayshineManager.Instance.GetYearWeekCount(year);
            if (year == DateTime.Now.Year)
            {
                endWeek = FayshineManager.GetWeeofYear(DateTime.Now);
            }

            int lastInCount = 0;
            int lastOutCount = 0;
            while (firstWeek <= endWeek)
            {
                HistoryPassengerFlow historyPassengerFlow = new HistoryPassengerFlow();

                //historyPassengerFlow.HistoryTime = startTime;
                // historyPassengerFlow.DisplayTitle = FayshineManager.Instance.GetWeekDayString(startTime
                historyPassengerFlow.MonthOrDayOrWeek = firstWeek;
                IEnumerable<int?> inCounts = from t in passengerflows
                                             where t.dt.Value == firstWeek && t.historytime.Value.Year == year && t.isIn == true
                                             select t.count;
                IEnumerable<int?> outCounts = from t in passengerflows
                                              where t.dt.Value == firstWeek && t.historytime.Value.Year == year && t.isIn == false
                                              select t.count;

                historyPassengerFlow.InCount = inCounts.Sum().Value;
                historyPassengerFlow.OutCount = outCounts.Sum().Value;
                historyPassengerFlow.AccumulateInCount = lastInCount + historyPassengerFlow.InCount;
                historyPassengerFlow.AccumulateOutCount = lastInCount + historyPassengerFlow.OutCount;
                historyPassengerFlow.StrandedCount = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
                historyPassengerFlow.AllInOut = historyPassengerFlow.InCount + historyPassengerFlow.OutCount;
                historyPassengerFlow.Differ = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
                lastInCount = historyPassengerFlow.AccumulateInCount;
                lastOutCount = historyPassengerFlow.AccumulateOutCount;

                yearWeeksPassengerFlow.Add(historyPassengerFlow);
                firstWeek++;
            }

            return yearWeeksPassengerFlow;
        }

        private List<HistoryPassengerFlow> GetGateWeekDayPassengerFlow(bool isSingleArea, List<passengerflowbydate> passengerflows, DateTime startTime, DateTime endTime)
        {
            List<HistoryPassengerFlow> historyPassengerFlows = new List<HistoryPassengerFlow>();
            HistoryPassengerFlow temHistoryPassengerFlow = null;
            if (isSingleArea)
            {
                var topAreaGate = this.MonitorAreaGateExts.Where(m => m.TypeID == 1).FirstOrDefault();
                if (topAreaGate != null)
                {
                    List<int> ids = new List<int>();
                    if (topAreaGate.IsSelected)
                    {
                        ids = GetGateIDsByArea(topAreaGate.ID);
                    }
                    else
                    {
                        ids = this.MonitorAreaGateExts.Where(m => m.IsSelected && m.TypeID != 1).Select(mm => mm.ID).ToList();
                    }
                    ids.each(id =>
                    {
                        var tempPassengerFlows = passengerflows.Where(entity => id == entity.gateID).ToList();
                        temHistoryPassengerFlow = ConvertGateDayHistoryPassengerFlow(tempPassengerFlows, startTime, endTime);
                        if (temHistoryPassengerFlow != null)
                        {
                            temHistoryPassengerFlow.DisplayTitle = GetGateName(id);
                            historyPassengerFlows.Add(temHistoryPassengerFlow);
                        }

                    });
                }
            }
            else
            {
                var selectAreaExts = this.AreaExtends.Where(a => a.IsSelected).ToList();
                selectAreaExts.each(s =>
                {
                    var ids = GetGateIDsByArea(s.ID);
                    var tempPassengerFlows = passengerflows.Where(entity => ids.Contains(entity.gateID)).ToList();
                    temHistoryPassengerFlow = ConvertGateDayHistoryPassengerFlow(tempPassengerFlows, startTime, endTime);
                    if (temHistoryPassengerFlow != null)
                    {
                        temHistoryPassengerFlow.DisplayTitle = s.Name;
                        historyPassengerFlows.Add(temHistoryPassengerFlow);
                    }
                });
            }

            return historyPassengerFlows;
        }

        private HistoryPassengerFlow ConvertGateDayHistoryPassengerFlow(List<passengerflowbydate> passengerflows, DateTime startTime, DateTime endTime)
        {
            HistoryPassengerFlow historyPassengerFlow = new HistoryPassengerFlow();

            IEnumerable<int?> inCounts = from t in passengerflows
                                         where t.isIn == true && t.historytime >= startTime
                                               && t.historytime <= endTime
                                         select t.count;
            IEnumerable<int?> outCounts = from t in passengerflows
                                          where t.isIn == false && t.historytime >= startTime
                                               && t.historytime <= endTime
                                          select t.count;

            historyPassengerFlow.InCount = inCounts.Sum().Value;
            historyPassengerFlow.OutCount = outCounts.Sum().Value;
            historyPassengerFlow.StrandedCount = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
            historyPassengerFlow.AllInOut = historyPassengerFlow.InCount + historyPassengerFlow.OutCount;
            historyPassengerFlow.Differ = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;

            return historyPassengerFlow;
        }

        #endregion

        #region 周每日客流统计


        public void RefreshWeekDayReport(bool isIn, DateTime dateTime1,DateTime dateTime2)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;

            var getWeekDayPassengerQuery = m_Context.GetPassengerflowByMultiWeekQuery(monitorAreaIDs, dateTime1, dateTime2);

            var loadMonthPassgnerQuery = m_Context.Load(getWeekDayPassengerQuery, (s) =>
            {
                if (!s.HasError)
                {
                    DateTime startTime = dateTime1;
                    DateTime endTime = dateTime1;
                    GetWeekStartAndEndTime(dateTime1, out startTime, out endTime);
                    var thisWeekDayPassneger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, startTime, endTime);
                    //var thisWeekGatePassenger = GetGateWeekDayPassengerFlow(isSingleArea, s.Entities.ToList(), startTime, endTime);

                    DateTime lastStartTime = dateTime2;
                    DateTime lastEndTime = dateTime2;
                    GetWeekStartAndEndTime(dateTime2, out lastStartTime, out lastEndTime);
                    var lastWeekDayPassenger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, lastStartTime, lastEndTime);

                    this.ComparePassengerFlows = GetWeekComparePassengerFlow(thisWeekDayPassneger, lastWeekDayPassenger);
                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(string.Empty, true, thisWeekDayPassneger, lastWeekDayPassenger);
                    }
                    
                }
            }, true);
        }

        private List<ComparePassengerFlow> GetWeekComparePassengerFlow(List<HistoryPassengerFlow> firstWeekPassengerFlows, List<HistoryPassengerFlow> secondWeedPassengerFlows)
        {
            List<ComparePassengerFlow> comparePassengerFlows = new List<ComparePassengerFlow>();

            int index = 0;
            ComparePassengerFlow tempCompare = null;
            int allFirstInCount = firstWeekPassengerFlows.Sum(s => s.InCount);
            int allFirstOutCount = firstWeekPassengerFlows.Sum(s => s.OutCount);
            int allSecInCount = secondWeedPassengerFlows.Sum(s => s.InCount);
            int allSecOutCount = secondWeedPassengerFlows.Sum(s => s.OutCount);
            decimal percent = 0;
            while (index < 7)
            {
                tempCompare = new ComparePassengerFlow();
                
                var firstWeekFlow = firstWeekPassengerFlows.Where(f => f.MonthOrDayOrWeek == index).First();
                var secWeekFlow = secondWeedPassengerFlows.Where(s => s.MonthOrDayOrWeek == index).First();

                tempCompare.DisplayTitle = firstWeekFlow.DisplayTitle;
                tempCompare.DisplayDate = string.Format("{0:MM-dd}", firstWeekFlow.HistoryTime);
                tempCompare.CompareDate = string.Format("{0:MM-dd}", secWeekFlow.HistoryTime);
                
                tempCompare.InCount = firstWeekFlow.InCount;
                percent = allFirstInCount > 0 ? ((decimal)tempCompare.InCount / allFirstInCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                tempCompare.InPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                tempCompare.CompareInCount = secWeekFlow.InCount;
                percent = allSecInCount > 0 ? ((decimal)tempCompare.CompareInCount / allSecInCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                tempCompare.CompareInPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                tempCompare.OutCount = firstWeekFlow.OutCount;
                percent = allFirstOutCount > 0 ? ((decimal)tempCompare.OutCount / allFirstOutCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                tempCompare.OutPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                tempCompare.CompareOutCount = secWeekFlow.OutCount;
                percent = allSecOutCount > 0 ? ((decimal)tempCompare.CompareOutCount / allSecOutCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                tempCompare.CompareOutPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                comparePassengerFlows.Add(tempCompare);
                index++;
            }

            tempCompare = new ComparePassengerFlow();
            tempCompare.DisplayDate = "总计";
            tempCompare.InCount = allFirstInCount;
            tempCompare.OutCount = allFirstOutCount;
            tempCompare.CompareInCount = allSecInCount;
            tempCompare.CompareOutCount = allSecOutCount;

            comparePassengerFlows.Add(tempCompare);

            return comparePassengerFlows;
        }


        #endregion

        #region 周进出客流圆饼图分析

        public void RefreshWeekInOutPieReport(bool isIn, DateTime dateTime)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;

            var getWeekDayPassengerQuery = m_Context.GetPassengerflowByWeekQuery(monitorAreaIDs, dateTime);

            var loadMonthPassgnerQuery = m_Context.Load(getWeekDayPassengerQuery, (s) =>
            {
                if (!s.HasError)
                {
                    DateTime startTime = dateTime;
                    DateTime endTime = dateTime;
                    GetWeekStartAndEndTime(dateTime, out startTime, out endTime);
                    var thisWeekDayPassneger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, startTime, endTime);
                    var thisWeekGatePassenger = GetGateWeekDayPassengerFlow(isSingleArea, s.Entities.ToList(), startTime, endTime);

                    DateTime lastStartTime = dateTime.AddDays(-7);
                    DateTime lastEndTime = dateTime.AddDays(-7);
                    GetWeekStartAndEndTime(dateTime.AddDays(-7), out lastStartTime, out lastEndTime);
                    var lastWeekDayPassenger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, lastStartTime, lastEndTime);

                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(string.Empty,true,thisWeekDayPassneger, lastWeekDayPassenger);
                    }
                }
            }, true);
        }

        #endregion

        #region 周客流分时段对比

        public void RefreshWeekDurationReport(bool isIn, DateTime dtWeekStart, DateTime dtWeekEnd)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;

            //Set DateTime Query
            var getDurationPassengerQuery = m_Context.GetPassengerflowbySpecifiedTimeQuery(monitorAreaIDs, 30, dtWeekStart, dtWeekEnd);
            var loadDuaraionPassgnerQuery = m_Context.Load(getDurationPassengerQuery, (a) =>
            {
                if (!a.HasError)
                {
                    var firstDurationPassengers = GetAnyDurationHistoryPassengerFlow(isSingleArea, a.Entities, dtWeekStart, dtWeekEnd, null);
                    this.TempPassengerFlowByMin = a.Entities;
                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(string.Empty, isIn, null, null);
                                                    //CompoundHistoryPassengerFlow(false, firstDurationPassengers), null);
                    }

                }
            }, true);

        }

        #endregion

        #region 周各门客流统计分析

        public void RefreshWeekGateReport(bool isIn, DateTime dateTime)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;
            //this.CurveTitle = GetYearReportTitle(isIn, isSingleArea, dateTime.Year);

            var getWeekDayPassengerQuery = m_Context.GetPassengerflowByWeekQuery(monitorAreaIDs, dateTime);

            var loadMonthPassgnerQuery = m_Context.Load(getWeekDayPassengerQuery, (s) =>
            {
                if (!s.HasError)
                {
                    DateTime startTime = dateTime;
                    DateTime endTime = dateTime;
                    GetWeekStartAndEndTime(dateTime, out startTime, out endTime);
                    this.WeekPassengerFlows.Clear();
                    var thisWeekDayPassneger = GetWeekPassengerFlow(isSingleArea, s.Entities, startTime, endTime);
                    this.WeekPassengerFlows = thisWeekDayPassneger;

                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(string.Empty, true, null, null);
                    }

                    //var thisWeekGatePassenger = GetGateWeekDayPassengerFlow(isSingleArea, s.Entities.ToList(), startTime, endTime);

                    //DateTime lastStartTime = dateTime.AddDays(-7);
                    //DateTime lastEndTime = dateTime.AddDays(-7);
                    //GetWeekStartAndEndTime(dateTime.AddDays(-7), out lastStartTime, out lastEndTime);
                    //var lastWeekDayPassenger = GetWeekDayPassengerFlow(isSingleArea, s.Entities, lastStartTime, lastEndTime);
                }
            }, true);

        }

        public List<WeekPassengerFlow> GetWeekPassengerFlow(bool isSingleArea, IEnumerable<passengerflowbydate> passengerflows, DateTime startTime, DateTime endTime)
        {
            List<WeekPassengerFlow> weekPassengerFlows = new List<WeekPassengerFlow>();
            WeekPassengerFlow temHistoryPassengerFlow = null;
            if (isSingleArea)
            {
                var topAreaGate = this.MonitorAreaGateExts.Where(m => m.TypeID == 1).FirstOrDefault();
                if (topAreaGate != null)
                {
                    List<int> ids = new List<int>();
                    if (topAreaGate.IsSelected)
                    {
                        ids = GetGateIDsByArea(topAreaGate.ID);
                    }
                    else
                    {
                        ids = this.MonitorAreaGateExts.Where(m => m.IsSelected && m.TypeID != 1).Select(mm => mm.ID).ToList();
                    }
                    ids.each(id =>
                    {
                        var tempPassengerFlows = passengerflows.Where(entity => id == entity.gateID).ToList();
                        temHistoryPassengerFlow = ConvertGateWeekPassengerFlow(tempPassengerFlows, startTime, endTime);
                        if (temHistoryPassengerFlow != null)
                        {
                            temHistoryPassengerFlow.DisplayTitle = GetGateName(id);
                            temHistoryPassengerFlow.GateID = id;
                            weekPassengerFlows.Add(temHistoryPassengerFlow);
                        }

                    });
                }
            }
            else
            {
                var selectAreaExts = this.AreaExtends.Where(a => a.IsSelected).ToList();
                selectAreaExts.each(s =>
                {
                    var ids = GetGateIDsByArea(s.ID);
                    var tempPassengerFlows = passengerflows.Where(entity => ids.Contains(entity.gateID)).ToList();
                    temHistoryPassengerFlow = ConvertGateWeekPassengerFlow(tempPassengerFlows, startTime, endTime);
                    if (temHistoryPassengerFlow != null)
                    {
                        temHistoryPassengerFlow.DisplayTitle = s.Name;
                        temHistoryPassengerFlow.GateID = s.ID;
                        weekPassengerFlows.Add(temHistoryPassengerFlow);
                    }
                });
            }

            ComputeWeekPassengerFlowPercent(weekPassengerFlows);

            return weekPassengerFlows;
        }

        public WeekPassengerFlow ConvertGateWeekPassengerFlow(List<passengerflowbydate> passengerFlowbyDates, DateTime startTime, DateTime endTime)
        {
            WeekPassengerFlow weekPassengerFlow = new WeekPassengerFlow();

            int weekDay = 0;
            while (weekDay < 7)
            {
                IEnumerable<int?> inCounts = from t in passengerFlowbyDates
                                             where t.isIn == true && t.historytime >= startTime
                                                   && t.historytime <= endTime && t.dt == weekDay
                                             select t.count;
                IEnumerable<int?> outCounts = from t in passengerFlowbyDates
                                              where t.isIn == false && t.historytime >= startTime
                                                   && t.historytime <= endTime && t.dt == weekDay
                                              select t.count;
                if (weekDay == 0)
                {
                    weekPassengerFlow.MonDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.MonDayOutCount = outCounts.Sum().Value;
                }
                else if (weekDay == 1)
                {
                    weekPassengerFlow.TueDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.TueDayOutCount = outCounts.Sum().Value;
                }
                else if (weekDay == 2)
                {
                    weekPassengerFlow.WedDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.WedDayOutCount = outCounts.Sum().Value;
                }
                else if (weekDay == 3)
                {
                    weekPassengerFlow.ThuDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.ThuDayOutCount = outCounts.Sum().Value;
                }
                else if (weekDay == 4)
                {
                    weekPassengerFlow.FriDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.FriDayOutCount = outCounts.Sum().Value;
                }
                else if (weekDay == 5)
                {
                    weekPassengerFlow.SatDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.SatDayOutCount = outCounts.Sum().Value;
                }
                else if (weekDay == 6)
                {
                    weekPassengerFlow.SunDayInCount = inCounts.Sum().Value;
                    weekPassengerFlow.SunDayOutCount = outCounts.Sum().Value;
                }
                weekDay++;
            }


            IEnumerable<int?> allInCounts = from t in passengerFlowbyDates
                                         where t.isIn == true && t.historytime >= startTime
                                               && t.historytime <= endTime
                                         select t.count;
            IEnumerable<int?> allOutCounts = from t in passengerFlowbyDates
                                          where t.isIn == false && t.historytime >= startTime
                                               && t.historytime <= endTime
                                          select t.count;

            weekPassengerFlow.ThisWeekInCount = allInCounts.Sum().Value;
            weekPassengerFlow.ThisWeekOutCount = allOutCounts.Sum().Value;



            DateTime lastStartTime = startTime.AddDays(-7);
            DateTime lastEndTime = startTime.AddDays(-7);
            GetWeekStartAndEndTime(startTime.AddDays(-7), out lastStartTime, out lastEndTime);

            IEnumerable<int?> allLastInCounts = from t in passengerFlowbyDates
                                                where t.isIn == true && t.historytime >= lastStartTime
                                                  && t.historytime <= lastEndTime
                                            select t.count;
            IEnumerable<int?> allLastOutCounts = from t in passengerFlowbyDates
                                                 where t.isIn == false && t.historytime >= lastStartTime
                                                  && t.historytime <= lastEndTime
                                             select t.count;

            weekPassengerFlow.LastWeekInCount = allLastInCounts.Sum().Value;
            weekPassengerFlow.LastWeekOutCount = allLastOutCounts.Sum().Value;

            return weekPassengerFlow;
        }

        public void ComputeWeekPassengerFlowPercent(List<WeekPassengerFlow> weekPassengerFlow)
        {
            int thisWeekAllGateInCount = weekPassengerFlow.Sum(s => s.ThisWeekInCount);
            int thisWeekAllGateOutCount = weekPassengerFlow.Sum(s => s.ThisWeekOutCount);
            int lastWeekAllGateInCount = weekPassengerFlow.Sum(s => s.LastWeekInCount);
            int lastWeekAllGateOutCount = weekPassengerFlow.Sum(s => s.LastWeekOutCount);

            decimal percent;
            weekPassengerFlow.each(w =>
            {
                percent = thisWeekAllGateInCount > 0 ? ((decimal)w.ThisWeekInCount / thisWeekAllGateInCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                w.ThisWeekInPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                percent = thisWeekAllGateOutCount > 0 ? ((decimal)w.ThisWeekOutCount / thisWeekAllGateOutCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                w.ThisWeekOutPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                percent = lastWeekAllGateInCount > 0 ? ((decimal)w.LastWeekInCount / lastWeekAllGateInCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                w.LastWeekInPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

                percent = lastWeekAllGateOutCount > 0 ? ((decimal)w.LastWeekOutCount / lastWeekAllGateOutCount) * 100 : 0;
                percent = Math.Round(percent, 2);
                w.LastWeekOutPercent = percent > 0 ? percent.ToString() + "%" : string.Empty;

            });
        }

        #endregion

#region 周每日各店客流对比

        public void RefreshWeekAllShopReport(bool isIn, DateTime dateTime)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            this.AreaExtends.each(a => a.IsSelected = true);
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;
            //this.CurveTitle = GetYearReportTitle(isIn, isSingleArea, dateTime.Year);

            var getWeekDayPassengerQuery = m_Context.GetPassengerflowByWeekQuery(monitorAreaIDs, dateTime);

            var loadMonthPassgnerQuery = m_Context.Load(getWeekDayPassengerQuery, (s) =>
            {
                if (!s.HasError)
                {
                    DateTime startTime = dateTime;
                    DateTime endTime = dateTime;
                    GetWeekStartAndEndTime(dateTime, out startTime, out endTime);
                    this.WeekPassengerFlows.Clear();
                    var thisWeekDayPassneger = GetWeekPassengerFlow(isSingleArea, s.Entities, startTime, endTime);
                    this.WeekPassengerFlows = thisWeekDayPassneger;

                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(string.Empty, true, null, null);
                    }

                }
            }, true);

        }
#endregion
        #region 周同期客流比较

        public void RefreshWeekCompareReport(bool isIn, DateTime dateTime)
        {
            if (ResetHisotryChartEvent != null)
            {
                ResetHisotryChartEvent();
            }
            var selectAreaExt = this.AreaExtends.Where(a => a.IsSelected).ToList();
            List<int> monitorAreaIDs = new List<int>();
            selectAreaExt.each(s => { monitorAreaIDs.Add(s.ID); });
            bool isSingleArea = monitorAreaIDs.Count == 1 ? true : false;
            var getYearWeekPassengerQuery = m_Context.GetPassengerflowByYearWeekQuery(monitorAreaIDs, dateTime.Year);
            var loadYearPassgnerQuery = m_Context.Load(getYearWeekPassengerQuery, (t) =>
            {
                if (!t.HasError)
                {
                    var thisYearWeekPassneger = GetYearWeekPassengerFlow(isSingleArea, t.Entities, dateTime.Year);
                    var lastYearWeekPassenger = GetYearWeekPassengerFlow(isSingleArea, t.Entities, dateTime.Year - 1);
                    if (AppendHistoryPassengerFlow != null)
                    {
                        AppendHistoryPassengerFlow(this.CurveTitle, isIn, thisYearWeekPassneger, lastYearWeekPassenger);
                    }
                
                }
            }, true);

        }

        #endregion

        #region Private Methods

        public List<int> GetGateIDsByArea(int areaID)
        {
            List<int> ids = new List<int>();

            var area = this.AreaExtends.Where(a => a.ID == areaID).FirstOrDefault().Tag as area;
            if (area != null)
            {
                area.gates.each(g => { ids.Add(g.ID); });
            }
            return ids;
        }

        private string GetAreaName(int areaID)
        {
            return this.AreaExtends.Where(a => a.ID == areaID).First().Name;
        }

        private string GetMonthDisplayTitle(int month)
        {
            string monthName = "一月";

            switch (month)
            {
                case 1:
                    monthName = "一月";
                    break;
                case 2:
                    monthName = "二月";
                    break;
                case 3:
                    monthName = "三月";
                    break;
                case 4:
                    monthName = "四月";
                    break;
                case 5:
                    monthName = "五月";
                    break;
                case 6:
                    monthName = "六月";
                    break;
                case 7:
                    monthName = "七月";
                    break;
                case 8:
                    monthName = "八月";
                    break;
                case 9:
                    monthName = "九月";
                    break;
                case 10:
                    monthName = "十月";
                    break;
                case 11:
                    monthName = "十一月";
                    break;
                case 12:
                    monthName = "十二月";
                    break;

            }

            return monthName;
        }


        public string GetGateName(int id)
        {
            string title = string.Empty;

            var a = this.MonitorAreaGateExts.Where(m => m.ID == id).FirstOrDefault();
            if (a != null)
            {
                title = a.Name;
            }

            return title;
        }

        private List<HistoryPassengerFlow> ConvertDurationHistoryPassengerFlow(List<passengerflowbymin> passengerflows,
                                                                       int minsDuration,
                                                                       DateTime dtRangeStart,
                                                                       DateTime dtRangeEnd,
                                                                       List<DayOfWeek> enableWeeks)
        {
            List<HistoryPassengerFlow> dayRealTimePassengerFlow = new List<HistoryPassengerFlow>();
            DateTime startTime = dtRangeStart;
            int lastInCount = 0;
            int lastOutCount = 0;
            bool isIncludeWeek = true;
            while (startTime <= dtRangeEnd)
            {
                if (enableWeeks != null && enableWeeks.Count > 0)
                {
                    if (enableWeeks.Contains(startTime.DayOfWeek))
                    {
                        isIncludeWeek = true;
                    }
                    else
                    {
                        isIncludeWeek = false;
                    }
                }
                else
                {
                    isIncludeWeek = true;
                }
                if (isIncludeWeek)
                {
                    HistoryPassengerFlow historyPassengerFlow = new HistoryPassengerFlow();
                    //historyPassengerFlow.DisplayTitle = dtRangeStart.ToShortDateString() + " 至 " + dtRangeEnd.ToShortDateString();
                    historyPassengerFlow.HistoryTime = startTime;
                    IEnumerable<int?> inCounts = from t in passengerflows
                                                 where t.dt == startTime && t.isIn == true
                                                 select t.count;
                    IEnumerable<int?> outCounts = from t in passengerflows
                                                  where t.dt == startTime && t.isIn == false
                                                  select t.count;

                    historyPassengerFlow.InCount = inCounts.Sum().Value;
                    historyPassengerFlow.OutCount = outCounts.Sum().Value;
                    historyPassengerFlow.AccumulateInCount = lastInCount + historyPassengerFlow.InCount;
                    historyPassengerFlow.AccumulateOutCount = lastInCount + historyPassengerFlow.OutCount;
                    historyPassengerFlow.StrandedCount = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
                    historyPassengerFlow.AllInOut = historyPassengerFlow.InCount + historyPassengerFlow.OutCount;
                    historyPassengerFlow.Differ = historyPassengerFlow.InCount - historyPassengerFlow.OutCount;
                    lastInCount = historyPassengerFlow.AccumulateInCount;
                    lastOutCount = historyPassengerFlow.AccumulateOutCount;

                    dayRealTimePassengerFlow.Add(historyPassengerFlow);
                }
                startTime = startTime.AddMinutes(minsDuration);
            }
            return dayRealTimePassengerFlow;
        }

        private List<HistoryPassengerFlow> GetAnyDurationHistoryPassengerFlow(bool isSingleArea,
                                                                                    IEnumerable<passengerflowbymin> entities,
                                                                                    DateTime startTime,
                                                                                    DateTime endTime,
                                                                                    List<DayOfWeek> enbaleWeeks)
        {
            List<HistoryPassengerFlow> historyPassengerFlows = new List<HistoryPassengerFlow>();
            List<passengerflowbymin> tempPassengerFlows = new List<passengerflowbymin>();
            if (isSingleArea)
            {
                var topAreaGate = this.MonitorAreaGateExts.Where(m => m.TypeID == 1).FirstOrDefault();
                if (topAreaGate != null)
                {
                    List<int> ids = new List<int>();
                    if (topAreaGate.IsSelected)
                    {
                        ids = GetGateIDsByArea(topAreaGate.ID);
                    }
                    else
                    {
                        ids = this.MonitorAreaGateExts.Where(m => m.IsSelected && m.TypeID != 1).Select(mm => mm.ID).ToList();
                    }
                    tempPassengerFlows = entities.Where(entity => ids.Contains(entity.gateID)).ToList();
                }
            }
            else
            {
                tempPassengerFlows = entities.ToList();
            }

            historyPassengerFlows = ConvertDurationHistoryPassengerFlow(tempPassengerFlows, 30, startTime, endTime, enbaleWeeks);

            return historyPassengerFlows;
        }

        private List<HistoryPassengerFlow> CompoundHistoryPassengerFlow(bool isAvg, List<HistoryPassengerFlow> historyPassengerFlow)
        {
            List<HistoryPassengerFlow> computedHistoryPassengerFlow = new List<HistoryPassengerFlow>();

            DateTime startTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);
            DateTime endTime = startTime.AddDays(1);

            while (startTime < endTime)
            {
                HistoryPassengerFlow tempPassgnegerFlow = new HistoryPassengerFlow();
                //historyPassengerFlow.DisplayTitle = dtRangeStart.ToShortDateString() + " 至 " + dtRangeEnd.ToShortDateString();
                tempPassgnegerFlow.HistoryTime = startTime;
                IEnumerable<int> inCounts = from t in historyPassengerFlow
                                            where t.HistoryTime.Hour == startTime.Hour &&
                                                  t.HistoryTime.Minute == startTime.Minute &&
                                                  t.HistoryTime.Second == startTime.Second
                                            select t.InCount;
                IEnumerable<int> outCounts = from t in historyPassengerFlow
                                             where t.HistoryTime.Hour == startTime.Hour &&
                                                 t.HistoryTime.Minute == startTime.Minute &&
                                                 t.HistoryTime.Second == startTime.Second
                                             select t.OutCount;
                IEnumerable<int> strandedCount = from t in historyPassengerFlow
                                                 where t.HistoryTime.Hour == startTime.Hour &&
                                                  t.HistoryTime.Minute == startTime.Minute &&
                                                  t.HistoryTime.Second == startTime.Second
                                                 select t.StrandedCount;
                tempPassgnegerFlow.InCount = inCounts.Any() ? (isAvg ? Convert.ToInt32(inCounts.Average()) : inCounts.Sum()) : 0;
                tempPassgnegerFlow.OutCount = outCounts.Any() ? (isAvg ? Convert.ToInt32(outCounts.Average()) : outCounts.Sum()) : 0;
                tempPassgnegerFlow.AllInOut = tempPassgnegerFlow.InCount + tempPassgnegerFlow.OutCount;
                tempPassgnegerFlow.StrandedCount = strandedCount.Any() ? (isAvg ? Convert.ToInt32(strandedCount.Average()) : strandedCount.Sum()) : 0;
                computedHistoryPassengerFlow.Add(tempPassgnegerFlow);
                startTime = startTime.AddMinutes(30);

            }

            return computedHistoryPassengerFlow;
        }

        public void GetWeekStartAndEndTime(DateTime dateTime, out DateTime startTime, out DateTime endTime)
        {
            startTime = dateTime;
            endTime = dateTime;
            switch (dateTime.DayOfWeek)
            {
                case DayOfWeek.Sunday:
                    endTime = dateTime.AddDays(1);
                    startTime = dateTime.AddDays(-6);
                    break;
                case DayOfWeek.Monday:
                    startTime = dateTime;
                    endTime = dateTime.AddDays(7);
                    break;
                case DayOfWeek.Tuesday:
                    startTime = dateTime.AddDays(-1);
                    endTime = dateTime.AddDays(6);
                    break;
                case DayOfWeek.Wednesday:
                    startTime = dateTime.AddDays(-2);
                    endTime = dateTime.AddDays(5);
                    break;
                case DayOfWeek.Thursday:
                    startTime = dateTime.AddDays(-3);
                    endTime = dateTime.AddDays(4);
                    break;
                case DayOfWeek.Friday:
                    startTime = dateTime.AddDays(-4);
                    endTime = dateTime.AddDays(3);
                    break;
                case DayOfWeek.Saturday:
                    startTime = dateTime.AddDays(-5);
                    endTime = dateTime.AddDays(2);
                    break;
            }
        }

        #endregion

        public void UpdateCheckedAreas()
        {
            m_checkedAreas = this.AreaExtends.Where(a => a.IsSelected).ToList();
            m_checkedGates = this.MonitorAreaGateExts.Where(g => g.IsSelected).ToList();
        }

        private string GetCheckedGatesText()
        {
            string sRet = string.Empty;

            if (m_checkedGates != null && m_checkedGates.Count > 0)
            {
                if (m_checkedGates.Count == MonitorAreaGateExts.Count)
                {
                    sRet = "所有";
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    m_checkedGates.ForEach(g =>
                    {
                        sb.AppendFormat(", {0}", g.Name);
                    });
                    sRet = sb.ToString().TrimStart(",".ToCharArray());
                }
            }

            return sRet;
        }

        internal string GetCheckedAreasText()
        {
            string sRet = string.Empty;

            if (m_checkedAreas != null && m_checkedAreas.Count > 0)
            {
                if (m_checkedAreas.Count == AreaExtends.Count)
                {
                    sRet = string.Format("(店铺 -- 所有 -- )");
                }
                else if (m_checkedAreas.Count == 1)
                {
                    // Need list gates
                    string gates = GetCheckedGatesText();
                    sRet = string.Format("(店铺 -- {0} -- 门 -- {1} --)", m_checkedAreas[0].Name, gates);
                }
                else if (m_checkedAreas.Count > 1)
                {
                    // Just list areas
                    StringBuilder sb = new StringBuilder();
                    m_checkedAreas.ForEach(a =>
                    {
                        sb.AppendFormat(", {0}", a.Name);
                    });
                    sRet = sb.ToString().TrimStart(",".ToCharArray());
                    sRet = string.Format("(店铺 -- {0} -- )", sRet);
                }
                else
                {
                    Debug.Assert(false, "No area checked");
                }
            }

            return sRet;
        }


        #region INotifyPropertyChanged Interface

        public event PropertyChangedEventHandler PropertyChanged;
        public void NofityPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }
}

